package com.gitee.wsl.io.storage.strategy

import com.gitee.wsl.io.storage.event.ItemEvent
import com.gitee.wsl.io.storage.event.ItemEventType
import com.gitee.wsl.io.storage.load.Transaction
import kotlin.time.Duration


interface KottageStrategyOperator {
    /**
     * This should be called in transaction
     */
    suspend fun updateItemLastRead(transaction: KottageTransaction, key: String, itemType: String, now: Long)

    /**
     * delete least recently used items
     * existing items in ItemList are ignored
     * This should be called in transaction
     */
    suspend fun deleteLeastRecentlyUsed(transaction: KottageTransaction, itemType: String, limit: Long)

    /**
     * delete older created items
     * existing items in ItemList are ignored
     * This should be called in transaction
     */
    suspend fun deleteOlderItems(transaction: KottageTransaction, itemType: String, limit: Long)

    /**
     * delete expired items
     * existing items in ItemList are ignored
     * This should be called in transaction
     *
     * @return deleted items count
     */
    suspend fun deleteExpiredItems(transaction: KottageTransaction, itemType: String, now: Long): Long

    /**
     * This should be called in transaction
     *
     * @return Event id
     */
    suspend fun addEvent(
        transaction: Transaction,
        now: Long,
        eventType: ItemEventType,
        eventExpireTime: Duration?,
        itemType: String,
        itemKey: String,
        itemListId: String?,
        itemListType: String?,
        maxEventEntryCount: Long
    ): String

    /**
     * Get events
     * This should be called in transaction
     */
    suspend fun getEvents(
        transaction: Transaction,
        afterUnixTimeMillisAt: Long,
        limit: Long? = null
    ): List<ItemEvent>

    /**
     * Get Item events
     * This should be called in transaction
     */
    suspend fun getItemEvents(
        transaction: Transaction,
        itemType: String,
        afterUnixTimeMillisAt: Long,
        limit: Long? = null
    ): List<ItemEvent>

    /**
     * Get List events
     * This should be called in transaction
     */
    suspend fun getListEvents(
        transaction: Transaction,
        listType: String,
        afterUnixTimeMillisAt: Long,
        limit: Long? = null
    ): List<ItemEvent>

}
